/**
 * @file STL_ThreadCheck.h
 * @author Derek Liu (yjkhtddx@sina.com)
 * @brief 
 * @version 2.00.05
 * @date 2021-12-12
 * 
 * @copyright Copyright Sci-Tech Laboratories (c) 2021
 * 
 */

#ifndef __STL_DEBUG_H__
#define __STL_DEBUG_H__

#include <map>
#include <list>
#include <string>
#include <stdlib.h>
#include <thread>
#include <mutex>
#include <stdint.h>
#include "STL_ModLog.h"

namespace STL
{

    class STL_ThreadCheck : public STL_ModLog
    {
    public:
        void lockCheckLog(std::string log)
        {
            modlog_debug("%s", log.c_str());
        }

    public:
        typedef struct ThreadCheckTask
        {
            uint64_t index;
            std::thread::id id;
            std::string tag;
            long long timeout;
            long long lastCheck;
            bool isResident;
            std::string describe;
        } DebugTask;

    private:
        STL_ThreadCheck();
        ~STL_ThreadCheck();

    public:
        static STL_ThreadCheck *getInstance()
        {
            static STL_ThreadCheck instance;
            return &instance;
        }

    public:
        static bool s_working;
        static void checkThread();
        void checkTasks();

    public:
        static uint64_t s_thread_index;

    public:
        // 添加检测任务
        void AddCheckTask(std::string tag, long long msTimeout, std::string describe = "", bool isResident = false);
        void SetCheckTaskDescribe(std::string describe);
        void KeepAliveCheckTask(std::string describe = "");
        void DeleteCheckTask();

    private:
        std::string getCheckTaskInfo(std::list<STL_ThreadCheck::ThreadCheckTask /*task*/>::iterator it);

    private:
        std::mutex m_taskListMutex;
        std::list<STL_ThreadCheck::ThreadCheckTask /*task*/> m_taskList;
    };

    class STL_LockCheck
    {
    private:
        std::string m_tag;

    public:
        STL_LockCheck(std::string tag) : m_tag(tag)
        {
            STL_ThreadCheck::getInstance()->lockCheckLog(std::string("STL_LockCheck [start] ") + m_tag);
        }
        ~STL_LockCheck()
        {
            STL_ThreadCheck::getInstance()->lockCheckLog(std::string("STL_LockCheck [end] ") + m_tag);
        };
    };
} // namespace STL
#endif // __STL_DEBUG_H__
